home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Libraries / CW GUSI 1.6.4 / src / GUSIMacFile.cp < prev    next >
Text File  |  1995-08-25  |  4KB  |  181 lines

  1. /*********************************************************************
  2. Project    :    GUSI                -    Grand Unified Socket Interface
  3. File        :    GUSIMacFile.cp-    Straight file sockets
  4. Author    :    Matthias Neeracher <neeri@iis.ee.ethz.ch>
  5. Language    :    MPW C++
  6.  
  7. $Log: GUSIFile.cp,v $
  8. *********************************************************************/
  9.  
  10. #include "GUSIFile_P.h"
  11.  
  12. #include <IOCtl.h>
  13.  
  14. #pragma segment GUSI
  15.  
  16. /************************ AppleFileSocket members ************************/
  17.  
  18. MacFileSocket * MacFileSocket::open(const TFileSpec & spec, int flags)
  19. {
  20.     char                    permission;
  21.     short                    fRef;
  22.     OSErr                    err;
  23.     MacFileSocket *    sock;
  24.     
  25.     switch (flags & 3) {
  26.     case O_RDONLY:        permission = fsRdPerm;         break;
  27.     case O_WRONLY:        permission = fsWrPerm;         break;
  28.     case O_RDWR:        permission = fsRdWrPerm;     break;
  29.     }
  30.     
  31.     if (err = HOpenDF(spec.vRefNum, spec.parID, spec.name, permission, &fRef)) {
  32.         // File not found, but might be creatable
  33.         if (err == fnfErr && flags & O_CREAT) {
  34.             err = HCreate(spec.vRefNum, spec.parID, spec.name, 'MPS ', 'TEXT');
  35.             if (!err || err == dupFNErr)
  36.                 err = HOpenDF(spec.vRefNum, spec.parID, spec.name, permission, &fRef);
  37.         }
  38.         switch (err) {
  39.         case noErr:
  40.             break;
  41.         case afpObjectTypeErr:
  42.             return (MacFileSocket *)GUSI_error_nil(EISDIR);
  43.         default:        
  44.             if (File_error(err) == -1)
  45.                 return (MacFileSocket *) nil;
  46.         }
  47.     } else if (flags & O_EXCL) {
  48.         FSClose(fRef);
  49.         return (MacFileSocket *)GUSI_error_nil(EEXIST);
  50.     }
  51.         
  52.     if (flags & O_TRUNC)
  53.         SetEOF(fRef, 0);
  54.         
  55.     sock = new MacFileSocket(fRef);
  56.     
  57.     if (sock) { 
  58.         sock->append = (flags & O_APPEND) != 0; 
  59.     
  60.         return sock;
  61.     } else {
  62.         FSClose(fRef);
  63.         return (MacFileSocket *)GUSI_error_nil(ENOMEM);
  64.     }
  65. }
  66.  
  67. int MacFileSocket::read(void * buffer, int buflen)
  68. {
  69.     OSErr    err;
  70.     long    length = buflen;
  71.     
  72.     switch (err = FSRead(fRefNum, &length, buffer)) {
  73.     case eofErr:
  74.     case noErr:
  75.         return int(length);
  76.     default:    
  77.         return File_error(err);
  78.     }
  79. }
  80.  
  81. int MacFileSocket::write(void * buffer, int buflen)
  82. {
  83.     long    length = buflen;
  84.     
  85.     PrepareWrite();
  86.     
  87.     if (File_error(FSWrite(fRefNum, &length, buffer)))
  88.         return -1;
  89.     else
  90.         return int(length);
  91. }
  92.  
  93. int MacFileSocket::ioctl(unsigned int request, void *argp)
  94. {
  95.     switch (request) {
  96.     case FIONREAD:
  97.         long     eof;
  98.         long    pos;
  99.         
  100.         if (File_error(GetEOF(fRefNum, &eof)))
  101.             return -1; 
  102.         if (File_error(GetFPos(fRefNum, &pos)))
  103.             return -1; 
  104.  
  105.         *(long *) argp    = eof - pos;
  106.         
  107.         return 0;
  108.     default :
  109.         return FileSocket::ioctl(request, argp);
  110.     }
  111. }
  112.  
  113. long MacFileSocket::lseek(long offset, int whence)
  114. {    
  115.     long    eof;
  116.     long    pos;
  117.     
  118.     if (File_error(GetEOF(fRefNum, &eof)))
  119.         return -1; 
  120.     
  121.     switch (whence) {
  122.     case SEEK_CUR:
  123.         if (File_error(GetFPos(fRefNum, &pos)))
  124.             return -1; 
  125.         break;
  126.     case SEEK_END:
  127.         pos = eof;
  128.         break;
  129.     case SEEK_SET:
  130.         pos = 0;
  131.         break;
  132.     default:
  133.         return GUSI_error(EINVAL);
  134.     }
  135.     
  136.     pos += offset;
  137.     
  138.     if (pos > eof) {
  139.         if (File_error(SetFPos(fRefNum, fsFromStart, eof)))
  140.             return -1;
  141.  
  142.         char * buf = NewPtrClear(1024);
  143.         long     portion = 1;
  144.         long     rest;
  145.         
  146.         for (rest = pos - eof; rest && portion; rest -= portion) {
  147.             portion = rest > 1024 ? 1024 : rest;
  148.             if (File_error(FSWrite(fRefNum, &portion, buf))) {
  149.                 DisposPtr(buf);
  150.                 
  151.                 return -1;
  152.             }
  153.         }
  154.         
  155.         DisposPtr(buf);
  156.         if (rest)
  157.             return GUSI_error(ENOSPC);
  158.     } else if (pos < 0)
  159.         return GUSI_error(EINVAL);
  160.     
  161.     return File_error(SetFPos(fRefNum, fsFromStart, pos)) ? -1 : pos;
  162. }
  163.  
  164. int MacFileSocket::ftruncate(long offset)
  165. {    
  166.     long pos;
  167.     
  168.     if (lseek(offset, SEEK_SET) == -1)
  169.         return -1;
  170.     
  171.     if (File_error(GetFPos(fRefNum, &pos)))
  172.         return -1;
  173.     
  174.     return File_error(SetEOF(fRefNum, pos));
  175. }
  176.  
  177. MacFileSocket::~MacFileSocket()
  178. {
  179.     FSClose(fRefNum);
  180. }
  181.